/*
 * Copyright 2025 The JA-SIG Collaborative. All rights reserved.
 * distributed with this file and available online at
 */
package com.lap.auth.adapter.driven.web.api;

import com.lap.auth.application.api.ApiAppService;
import com.lap.auth.application.api.command.CreateApiCmd;
import com.lap.auth.application.api.command.CreateApisCmd;
import com.lap.auth.application.api.command.UploadApiCmd;
import com.lap.auth.application.api.dto.ApiTreeDto;
import com.lap.watchdog.starter.annotation.RepeatSubmit;
import com.lap.web.starter.api.ApiResource;
import com.lap.web.starter.api.builder.ApiScanner;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

/**
 * 提供API接口restful接口层:
 *
 * <ol>
 *   <li>业务规则，原则上不做任何业务逻辑处理，仅仅是技术入口
 *   <li>命名规则，语义上明确接口做什么，推荐使用 Restful 命名 + Verb风格方法名（适配Swagger、Spring）:
 *       <ul>
 *         <li>分页使用 getXXXPage
 *         <li>获取单个 getXXById
 *         <li>保存使用 createXX
 *         <li>更新使用 updateXX
 *         <li>删除使用 deleteXX
 *       </ul>
 * </ol>
 *
 * @author Shuisheng Lao(劳水生)
 * @version 0.0.1
 */
@Tag(name = "API接口管理", description = "提供API接口基本操作，查询等")
@RequiredArgsConstructor
@RestController
@RequestMapping("api/v1/apis")
public class ApiController {

  private final ApiAppService apiAppService;

  @Operation(summary = "获取API资源树")
  @GetMapping
  public List<ApiTreeDto> getApiTree() {
    return apiAppService.queryApiTree();
  }

  @Operation(summary = "创建本地API资源")
  @RepeatSubmit
  @PostMapping("local")
  public void uploadApi(@RequestBody @Valid UploadApiCmd cmd) {
    List<ApiResource> list = ApiScanner.scan(cmd.getModule(), cmd.getName());
    apiAppService.createApis(cmd.getModule(), toCmdList(list, cmd.getViewType()));
  }

  @Operation(summary = "创建远程API资源")
  @RepeatSubmit
  @PostMapping("remote")
  public void createApi(@RequestBody @Valid CreateApisCmd cmd) {
    apiAppService.createApis(cmd.getModule(), cmd.getApiList());
  }

  private List<CreateApiCmd> toCmdList(List<ApiResource> list, Integer viewType) {
    return list.stream().map(item -> toCmd(item, viewType)).toList();
  }

  private CreateApiCmd toCmd(ApiResource apiResource, Integer viewType) {
    return CreateApiCmd.builder()
        .module(apiResource.getModule())
        .code(apiResource.getCode())
        .name(apiResource.getName())
        .parentCode(apiResource.getParentCode())
        .method(apiResource.getMethod())
        .uri(apiResource.getUri())
        .apiType(apiResource.getType().getCode())
        .viewType(viewType)
        .accessLevel(apiResource.getAccessLevel().getCode())
        .build();
  }
}
